﻿/*
SINACOR - BMF&Bovespa
Arquivo: ImportacaoBase.cs
Criado em: 14-jun-2010 17:46:59
Arquiteto Responsável: p-wgeneroso
*/
using System;
using System.Collections.Generic;
using System.Text;
using Sinacor.Infra.Common;
using Sinacor.Infra.UI.Common;
using Sinacor.Infra.Common.Exceptions;
using System.ComponentModel;
using Sinacor.UI.Bovespa.ImportacaoExportacao.Model.Parameter;
using PSE.ProcessManager.Common.Process;
using System.Xml;

namespace Sinacor.UI.Bovespa.ImportacaoExportacao.Presenter
{
    public abstract class ImportacaoExportacaoBase<TView, TFiltro> : BasePresenter<TView>
        where TView : IImportacaoExportacaoBase
        where TFiltro : IFiltroImportacaoExportacao
    {
        #region Atributos

        private TFiltro _filtro;
        private ProcessStatus _statusProcesso;
        private ModelCollection<Model.Calendario> _calendario;
        private List<IdentificacaoArquivo.IdentificacaoBase> _identificadoresArquivo;
        private Communication.Cliente _communicationCliente;

        #endregion

        #region Construtor

        /// 
        /// <param name="view"></param>
        public ImportacaoExportacaoBase(TView view)
            : this(view, null)
        {
        }

        /// 
        /// <param name="view"></param>
        public ImportacaoExportacaoBase(TView view, IFiltroImportacaoExportacao filtro)
            : base(view)
        {
            this._communicationCliente = new Sinacor.UI.Bovespa.ImportacaoExportacao.Communication.Cliente(this.Session);
            
            _statusProcesso = new ProcessStatus();
            _statusProcesso = new PSE.ProcessManager.Common.Process.ProcessStatus();
            _statusProcesso.Progress = 0;
            _statusProcesso.Step = String.Empty;

            _filtro = Activator.CreateInstance<TFiltro>();

            if (filtro != null)
            {
                _filtro.NomeArquivo = filtro.NomeArquivo;
                _filtro.TipoArquivo = filtro.TipoArquivo;
                _filtro.TipoSistema = filtro.TipoSistema;
                _filtro.DataPregao = filtro.DataPregao;
                _filtro.TipoFormatoArquivo = filtro.TipoFormatoArquivo;

                InicializarIdentificadoresArquivo();
            }

            (_filtro as BaseModel).PropertyChanged += new PropertyChangedEventHandler(Filtro_PropertyChanged);
        }

        public override void Dispose()
        {
            (_filtro as BaseModel).PropertyChanged -= Filtro_PropertyChanged;

            base.Dispose();
        }

        #endregion

        #region Propriedades

        public Model.Cliente ClienteAtual { get; set; }

        public TFiltro Filtro
        {
            get { return _filtro; }
            set { _filtro = value; }
        }

        public ProcessStatus StatusProcesso
        {
            get { return _statusProcesso; }
            set { _statusProcesso = value; }
        }

        public ModelCollection<Model.Calendario> Calendario
        {
            get
            {
                return _calendario;
            }
            set
            {
                _calendario = value;
            }
        }

        #endregion

        #region Propriedades Virtual

        protected virtual bool PermissaoProcessamentoArquivo 
        {
            get { return true; }
        }

        #endregion

        #region Métodos Abstract

        protected abstract void CancelarProcesso();
        protected abstract void InicializarTela();

        #endregion

        #region EventHandlers

        /// 
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Filtro_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "TipoArquivo")
            {
                View.AlterarPresenter(_filtro.TipoArquivo);
            }
        }

        public abstract void Executar();

        #endregion

        #region Métodos Públicos

        public void InicializarIdentificadoresArquivo()
        {
            _identificadoresArquivo = new List<IdentificacaoArquivo.IdentificacaoBase>();
            _identificadoresArquivo.Add(new IdentificacaoArquivo.Negocio(_filtro.TipoSistema));
            _identificadoresArquivo.Add(new IdentificacaoArquivo.Alocacao(_filtro.TipoSistema));
            _identificadoresArquivo.Add(new IdentificacaoArquivo.Distribuicao(_filtro.TipoSistema));
        }

        public void Cancelar()
        {
            if (View.ConfirmarCancelamento())
            {
                CancelarProcesso();
            }
        }

        public void Inicializar()
        {
            this.InicializarTela();
        }

        public bool VerificarPermissao()
        {
            if (!PermissaoProcessamentoArquivo)
                View.InformarUsuarioSemPermissao();

            return PermissaoProcessamentoArquivo;
        }

        /// <summary>
        /// Verificar Cliente
        /// </summary>
        public void VerificarCliente(string apelido)
        {
            this.ClienteAtual = null;

            try
            {
                Model.Parameter.FiltroCliente filtro = new Model.Parameter.FiltroCliente
                {
                    Apelido = apelido
                };

                this.ClienteAtual = _communicationCliente.ObterCliente(filtro);
            }
            catch (Exception ex)
            {
                this.HandleException(ex);
            }
        }

        public void LimparStatus()
        {
            StatusProcesso.Step = String.Empty;
            StatusProcesso.Progress = 0;
            StatusProcesso.StartedAt = default(DateTime);
            StatusProcesso.FinalizedAt = default(DateTime);

            View.AtualizarStatus();
        }

        public void DefinirTipoArquivo(string nomeArquivo)
        {
            //string header = null;
            //string funcao = null;
            //string tipoArquivo = null;

            System.IO.FileInfo fileInfo = null;
            XmlDocument xmlDoc = null;
            bool encontrouTipo = false;
            string infoArquivo = null;
            DateTime dataPregao;

            if (!String.IsNullOrEmpty(nomeArquivo))
            {
                fileInfo = new System.IO.FileInfo(nomeArquivo);

                if (fileInfo.Exists)
                {
                    try
                    {
                        xmlDoc = new XmlDocument();
                        xmlDoc.Load(nomeArquivo);
                        _filtro.TipoFormatoArquivo = Model.Enum.TipoFormatoArquivo.XML;
                    }
                    catch
                    {
                        _filtro.TipoFormatoArquivo = Model.Enum.TipoFormatoArquivo.TXT;
                        infoArquivo = System.IO.File.ReadAllText(nomeArquivo);
                    }

                    foreach (IdentificacaoArquivo.IdentificacaoBase identificador in _identificadoresArquivo)
                    {
                        if (_filtro.TipoFormatoArquivo == Model.Enum.TipoFormatoArquivo.TXT)
                        {
                            encontrouTipo = identificador.IdentificarArquivoTXT(infoArquivo);
                        }
                        else if (_filtro.TipoFormatoArquivo == Model.Enum.TipoFormatoArquivo.XML)
                        {
                            encontrouTipo = identificador.IdentificarArquivoXML(xmlDoc);
                        }
                        else
                        {
                            encontrouTipo = identificador.IdentificarArquivoXLS();
                        }

                        if (encontrouTipo)
                        {
                            if (identificador.VerificarPermissaoArquivoModulo())
                            {
                                if (identificador.VerificarPermissaoAcesso())
                                {
                                    if (identificador.IdentificarDataPregao(out dataPregao))
                                    {
                                        _filtro.DataPregao = dataPregao;

                                        if ((identificador.TipoArquivo == Model.Enum.TipoArquivo.NEGR
                                             || identificador.TipoArquivo == Model.Enum.TipoArquivo.NEGS)
                                             && _filtro is FiltroImportacaoNegocio)
                                            (_filtro as FiltroImportacaoNegocio).CodigoCorrespondente = null;

                                        _filtro.TipoArquivo = identificador.TipoArquivo;
                                    }
                                    else
                                    {
                                        if (_filtro.TipoArquivo != Model.Enum.TipoArquivo.Padrao)
                                            _filtro.TipoArquivo = Model.Enum.TipoArquivo.Padrao;

                                        View.InformarDataInvalida();
                                    }
                                }
                                else
                                {
                                    if (_filtro.TipoArquivo != Model.Enum.TipoArquivo.Padrao)
                                        _filtro.TipoArquivo = Model.Enum.TipoArquivo.Padrao;

                                    View.InformarUsuarioSemPermissao();
                                }
                            }
                            else
                            {
                                if (_filtro.TipoArquivo != Model.Enum.TipoArquivo.Padrao)
                                    _filtro.TipoArquivo = Model.Enum.TipoArquivo.Padrao;

                                View.InformarArquivoInvalido();
                            }

                            break;
                        }
                    }

                    if (_filtro.TipoFormatoArquivo == Model.Enum.TipoFormatoArquivo.XML)
                    {
                        xmlDoc = null;
                    }

                    if(!encontrouTipo)
                        InformarArquivoInvalido();
                }
                else
                {
                    if (_filtro.TipoArquivo != Model.Enum.TipoArquivo.Padrao)
                        _filtro.TipoArquivo = Model.Enum.TipoArquivo.Padrao;
                }
            }
            else
            {
                if (_filtro.TipoArquivo != Model.Enum.TipoArquivo.Padrao)
                    _filtro.TipoArquivo = Model.Enum.TipoArquivo.Padrao;
            }

            xmlDoc = null;
        }

        #endregion

        private void InformarArquivoInvalido()
        {
            if (_filtro.TipoArquivo != Model.Enum.TipoArquivo.Padrao)
                _filtro.TipoArquivo = Model.Enum.TipoArquivo.Padrao;

            View.InformarArquivoInvalido();
        }
    }
}
